/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#ifndef ds_Bitmap_h#define ds_Bitmap_h#include<algorithm>#include"jsalloc.h"#include"js/HashTable.h"#include"js/Vector.h"// This file provides two classes for representing bitmaps.//// DenseBitmap is an array of words of bits, with size linear in the maximum// bit which has been set on it.//// SparseBitmap provides a reasonably simple, reasonably efficient (in time and// space) implementation of a sparse bitmap. The basic representation is a hash// table whose entries are fixed length malloc'ed blocks of bits.namespacejs{classDenseBitmap{typedefVector<uintptr_t,0,SystemAllocPolicy>Data;Datadata;public:size_tsizeOfExcludingThis(mozilla::MallocSizeOfmallocSizeOf){returndata.sizeOfExcludingThis(mallocSizeOf);}boolensureSpace(size_tnumWords){MOZ_ASSERT(data.empty());returndata.appendN(0,numWords);}size_tnumWords()const{returndata.length();}uintptr_tword(size_ti)const{returndata[i];}uintptr_t&word(size_ti){returndata[i];}voidcopyBitsFrom(size_twordStart,size_tnumWords,uintptr_t*source){MOZ_ASSERT(wordStart+numWords<=data.length());mozilla::PodCopy(&data[wordStart],source,numWords);}voidbitwiseOrRangeInto(size_twordStart,size_tnumWords,uintptr_t*target)const{for(size_ti=0;i<numWords;i++)target[i]|=data[wordStart+i];}};classSparseBitmap{// The number of words of bits to use for each block mainly affects the// memory usage of the bitmap. To minimize overhead, bitmaps which are// expected to be fairly dense should have a large block size, and bitmaps// which are expected to be very sparse should have a small block size.staticconstsize_tWordsInBlock=4096/sizeof(uintptr_t);typedefmozilla::Array<uintptr_t,WordsInBlock>BitBlock;typedefHashMap<size_t,BitBlock*,DefaultHasher<size_t>,SystemAllocPolicy>Data;Datadata;staticsize_tblockStartWord(size_tword){returnword&~(WordsInBlock-1);}// Return the number of words in a BitBlock starting at |blockWord| which// are in |other|.staticsize_twordIntersectCount(size_tblockWord,constDenseBitmap&other){longcount=other.numWords()-blockWord;returnstd::min<size_t>((size_t)WordsInBlock,std::max<long>(count,0));}BitBlock&createBlock(Data::AddPtrp,size_tblockId);MOZ_ALWAYS_INLINEBitBlock*getBlock(size_tblockId)const{Data::Ptrp=data.lookup(blockId);returnp?p->value():nullptr;}MOZ_ALWAYS_INLINEBitBlock&getOrCreateBlock(size_tblockId){Data::AddPtrp=data.lookupForAdd(blockId);if(p)return*p->value();returncreateBlock(p,blockId);}public:boolinit(){returndata.init();}~SparseBitmap();size_tsizeOfExcludingThis(mozilla::MallocSizeOfmallocSizeOf);MOZ_ALWAYS_INLINEvoidsetBit(size_tbit){size_tword=bit/JS_BITS_PER_WORD;size_tblockWord=blockStartWord(word);BitBlock&block=getOrCreateBlock(blockWord/WordsInBlock);block[word-blockWord]|=uintptr_t(1)<<(bit%JS_BITS_PER_WORD);}boolgetBit(size_tbit)const;voidbitwiseAndWith(constDenseBitmap&other);voidbitwiseOrWith(constSparseBitmap&other);voidbitwiseOrInto(DenseBitmap&other)const;// Currently, this API only supports a range of words that is in a single bit block.voidbitwiseOrRangeInto(size_twordStart,size_tnumWords,uintptr_t*target)const;};}// namespace js#endif // ds_Bitmap_h